﻿//-------------------------------------------------------------------------------------------
// <copyright file="ListViewModel.cs" company="Russell Wilkins">
//     Copyright (c) Russell Wilkins 2014. All Rights Reserved.
// </copyright>
// <author>Russell Wilkins</author>
// <license href="license.txt">
//     The use of this software is governed by the Microsoft Public License
//     which is included with this distribution.
// </license>
//-------------------------------------------------------------------------------------------
namespace Ripple.TestClient.ViewModels
{
    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.ComponentModel;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Data;

    /// <summary>
    /// TODO: Describe the class
    /// </summary>
    public abstract class ListViewModel<TModel, TListItemViewModel> : ViewModel<TModel>
        where TModel : class, INotifyPropertyChanged
        where TListItemViewModel : class
    {
        public static readonly DependencyProperty SelectedItemProperty = DependencyProperty.Register("SelectedItem", typeof(TListItemViewModel), typeof(ListViewModel<TModel, TListItemViewModel>));
        private bool isConstructing;
        private bool isLoadingList;
        private ObservableCollection<TListItemViewModel> listItems;
        private bool listLoaded;

        /// <summary>
        /// Initializes a new instance of the <see cref="T:ListViewModel"/> class.
        /// </summary>
        public ListViewModel()
        {
            this.isConstructing = true;
            this.listItems = new ObservableCollection<TListItemViewModel>();
            this.CollectionView.Filter = new Predicate<object>(this.InternalListFilter);
            this.isConstructing = false;
        }

        public ICollectionView CollectionView
        {
            get
            {
                ICollectionView collectionView = CollectionViewSource.GetDefaultView(this.listItems);
                return collectionView;
            }
        }

        public ObservableCollection<TListItemViewModel> ListItems
        {
            get
            {
                if (!this.listLoaded && !this.isConstructing && !this.isLoadingList)
                {
                    this.Refresh();
                    //this.InternalRefeshList();
                }

                return this.listItems;
            }
        }

        public TListItemViewModel Selected
        {
            get
            {
                ICollectionView collectionView = CollectionViewSource.GetDefaultView(this.listItems);
                return collectionView.CurrentItem as TListItemViewModel;
            }
        }

        public TListItemViewModel SelectedItem
        {
            get { return (TListItemViewModel)GetValue(SelectedItemProperty); }

            set
            {
                SetValue(SelectedItemProperty, value);
            }
        }

        public virtual bool ListFilter(TListItemViewModel viewModel)
        {
            return true;
        }

        public void RefreshView()
        {
            this.CollectionView.Refresh();
        }

        protected override void InternalRefresh()
        {
            this.InternalRefeshList();
        }

        protected virtual void RefreshList()
        {
        }

        protected override void Reset()
        {
            this.listItems.Clear();
            this.listLoaded = false;
        }

        private bool InternalListFilter(object obj)
        {
            return this.ListFilter(obj as TListItemViewModel);
        }

        private void InternalRefeshList()
        {
            this.isLoadingList = true;
            this.RefreshList();
            this.listLoaded = true;
            this.isLoadingList = false;
        }
    }
}